package maggames.core;

import java.util.Random;

/**
 * Enum used to keep track of user actions.
 * 
 * @author BenjaminPLee
 * @version 1.0
 */
public enum Player {
	NONE,
	PLAYER1,
	PLAYER2,
	BOTH;
	
	/**
	 * Returns the result of adding p1 to p2.  If both are single player objects, then 
	 * BOTH is returned.  If one is NONE and the other a single player, the single player
	 * is returned.  If either is BOTH, BOTH is returned. Etc.
	 * 
	 * @param p1
	 * @param p2
	 * @return the addition of p1 and p2
	 */
	public static Player add(Player p1, Player p2) {
		Player result;
		
		if(p1 == Player.NONE) {
			result = p2;
		}
		else if(p2 == Player.NONE) {
			result = p1;
		}
		else if(p1 != p2) {
			// if either == BOTH, then result must be BOTH
			// if neither is == both and different, result = both
			result = Player.BOTH;
		}
		else {
			result = p1; // else p1 == p2 which means result doesn't change. choose one 
		}
		
		return result;
	}
	
	/**
	 * Returns the subtraction of p2 from p1.<br>
	 * For example:<br>
	 * P1 - NONE = P1<br>
	 * P1 - P2 = P1<br>
	 * P1 - P1 = NONE<br>
	 * BOTH - P1 = P2<br>
	 * NONE - * = NONE<br>
	 * BOTH - BOTH = NONE<br>
	 * etc...<br>
	 * 
	 * @param p1
	 * @param p2
	 * @return the result of subtracting p2 from p1
	 */
	public static Player subtract(Player p1, Player p2) {
		Player result = null;
		
		switch(p1) {
			case NONE:
				result = Player.NONE;
				break;
			case PLAYER1:
				if(p2 == Player.BOTH ||p2 == Player.PLAYER1)
					result = Player.NONE;
				else
					result = p1;
				break;
			case PLAYER2:
				if(p2 == Player.BOTH ||p2 == Player.PLAYER2)
					result = Player.NONE;
				else
					result = p1;
				break;
			case BOTH:
				result = Player.negate(p2);
				break;
			default:
				break;
		}
		
		return result; // TODO NOT YET IMPLEMENTED
	}
	
	/**
	 * Returns the negation of the given player.<br>
	 * For example:<br>
	 * -P1 = P2<br>
	 * -P2 = P1<br>
	 * -NONE = BOTH<br>
	 * -BOTH = NONE<br>
	 * 
	 * @param player
	 * @return the negation of the given player
	 */
	public static Player negate(Player player) {
		Player result = null;
		
		switch(player) {
			case NONE:
				result = Player.BOTH;
				break;
			case PLAYER1:
				result = Player.PLAYER2;
				break;
			case PLAYER2:
				result = Player.PLAYER1;
				break;
			case BOTH:
				result = Player.NONE;
				break;
			default:
				break;
		}
		
		return result;
	}
	
	/**
	 * Returns a randomly chosen Player.
	 * 
	 * @return random player
	 */
	public static Player getRandom() {
		Random rand = new Random();
		Player [] players = Player.values();
		int index = rand.nextInt(players.length);
		
		return players[index];
	}	
}